package com.ice.base.controller;

import com.ice.base.constant.HCNetSDK;
import com.ice.base.fileManager.constant.BaseFileConstant;
import com.ice.base.util.HexUtil;
import com.ice.base.util.RedisUtil;
import com.ice.body.business.service.ReagentStockService;
import com.ice.body.business.service.VideoMonitorService;
import com.ice.body.hardware.model.DeviceAir;
import com.ice.body.hardware.model.DeviceVideo;
import com.ice.body.hardware.service.DeviceAirService;
import com.ice.body.hardware.service.DeviceVideoService;
import com.ice.body.log.model.LogAir;
import com.ice.body.log.service.LogAirService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.net.InetAddress;
import java.net.Socket;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Configuration      //1.主要用于标记配置类，兼备Component的效果。
@EnableScheduling   // 2.开启定时任务
public class QuartzController {

    private final static String LOCK_ID = "happyJava";

    @Resource
    private ReagentStockService reagentStockService;
    @Resource
    private DeviceVideoService deviceVideoService;
    @Resource
    private DeviceAirService deviceAirService;
    @Resource
    private LogAirService logAirService;
    @Resource
    private VideoMonitorService videoMonitorService;




/*
    @Autowired
    DistributedLock distributedLock;

   // @Scheduled(cron = "0/10 * * * * ?")
    public void doSomething() {
        boolean lock = distributedLock.getLock(LOCK_ID, 15 * 1000);
        if (lock) {
            System.out.println("执行任务");
            distributedLock.releaseLock(LOCK_ID);
        } else {
            System.out.println("没有抢到锁");
        }
    }*/

    //3.添加定时任务

    //或直接指定时间间隔，例如：5秒
    //@Scheduled(fixedRate=5000)
    private void configureTasks() {
        DateTimeFormatter dtf2 =  DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        System.err.println("执行静态定时任务时间: " + dtf2.format(LocalDateTime.now()));
    }



    /**
     * 每天执行一次，删除大于30天的视频文件 0 50 23 * * ?
     */
    @Scheduled(cron = "0 55 23 * * ?")// 0 0/2 * * * ?
    private void delVideo() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        log.info("删除视频定时任务时间: " + formatter.format(LocalDateTime.now()));
        try {
            String locPath = BaseFileConstant.StaticPath.getLocPath(BaseFileConstant.StaticPath.STATIC_UPLOAD);
            File file  = new File(locPath);
            if(file != null){
                LocalDate date = LocalDate.now();
                DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMdd");
                String dateStr = date.format(fmt);
                int i = Integer.parseInt(dateStr);
                //数组指向文件夹中的文件和文件夹
                File[] fi=file.listFiles();
                //遍历文件和文件夹
                for(File f:fi){
                    String filename = f.getName();
                    if(f.isDirectory()){
                        continue;
                    }
                    String substring = filename.substring(0, 8);
                    int y = Integer.parseInt(substring);
                    if(i - y > 30){
                        //删除一个月文件
                        f.delete();
                    }
                }
                //数据库也需要删除大于30天的数据
                videoMonitorService.delete7Videos();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 每天执行一次，查询过期的试剂
     */
    @Scheduled(cron = "0 50 23 * * ?")// 0 0/2 * * * ?
    private void getExpireReagent() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        log.info("查询过期试剂定时任务时间: " + formatter.format(LocalDateTime.now()));
        try {
            reagentStockService.getExpireReagent();
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    @Resource
    private RedisUtil redisUtil;


    // 接口的实例，通过接口实例调用外部dll/so的函数
    static HCNetSDK sdk = HCNetSDK.INSTANCE;
    static int lUserID;
    static int lPreviewHandle;

    /**
     * 每晚9点 执行关闭视频 防止硬盘内存过大
     */
    @Scheduled(cron = "0 0 21 * * ?")// 0 0/2 * * * ?
    private void closeVideo() {
        ArrayList<DeviceVideo> list = deviceVideoService.getDistinctWarehouse();
        log.info("定时关闭摄像 房间数量："+list.size());
        if(null != list && list.size()>0){
            for (DeviceVideo videoModel : list) {
                HashMap<String,Integer> vMap = (HashMap)redisUtil.get(videoModel.getWarehouseId() + "vMap");
                if(!CollectionUtils.isEmpty(vMap)){
                    for (Map.Entry<String, Integer> entry : vMap.entrySet()) {
                        String user = entry.getKey();
                        Integer value = entry.getValue();
                        int userId = Integer.parseInt(user);

                        if (userId  >= 0){
                            if (sdk.NET_DVR_Logout(userId) == false) {
                                System.out.println("注销失败，错误码为" + sdk.NET_DVR_GetLastError());
                            }
                            sdk.NET_DVR_StopRealPlay(value);
                            //sdk.NET_DVR_Cleanup();
                            log.info("注销成功");

                        }else{
                            System.out.println("设备未登录");
                            //sdk.NET_DVR_Cleanup();
                            return;
                        }
                    }
                    redisUtil.del(videoModel.getWarehouseId()+"vMap");
                }
            }
        }
    }


    /**
     * 每天 8点 1点 下午5点
     * @return
     */
    @Scheduled(cron = "0 02 8,14,17 * * ?")// 0 0/2 * * * ?
    public void showMonitor() throws Exception {

        Socket socket = null;
        ArrayList<DeviceAir> deviceAirs = deviceAirService.selectAll();
        if(null == deviceAirs || deviceAirs.size() < 1){
            return;
        }
        try {
           // for (DeviceAir air : deviceAirs) {
            socket = new Socket(InetAddress.getByName("192.168.90.17"), Integer.parseInt("8234"));
            socket.setSoTimeout(5000);
            // 得到Socket连接的输出流
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            // 向服务器发送数据  1A190501028686860F   1A210502098686860F  1A210701018686860F
            out.write(HexUtil.hex2Bytes("1A210701048686860F"));
            // 立刻发送数据
            out.flush();
                //socket.shutdownOutput();
            DataInputStream in = new DataInputStream(socket.getInputStream());
            byte[] bytes = new byte[32];
            for (byte b:bytes) {
                System.out.print(b);
            }
            int size = in.read(bytes);
            String dataStr = "";
            if (size > 0) {
                dataStr = HexUtil.bytes2Hex(bytes).substring(0, 54);
            }
            socket.close();
                if (!StringUtils.isEmpty(dataStr)) {
                    int formaldehyde = Integer.parseInt(dataStr.substring(10, 14), 16);
                    int tvoc = Integer.parseInt(dataStr.substring(16, 20), 16);
                    int pm = Integer.parseInt(dataStr.substring(22, 26), 16);
                    int temperature = Integer.parseInt(dataStr.substring(28, 32), 16);
                    int humidity = Integer.parseInt(dataStr.substring(34, 38), 16);
                    int airQuality = Integer.parseInt(dataStr.substring(40, 44), 16);
                    int carbonDioxide = Integer.parseInt(dataStr.substring(46, 50), 16);
                    log.info("甲醛浓度：" + formaldehyde +",TVOC浓度：" + tvoc + ",PM2.5浓度：" +  pm
                             + ",温度：" + temperature + "湿度：" + humidity + "%," +
                             "空气质量指标：" + airQuality + "二氧化碳：" + carbonDioxide
                    );
                    //插入日志表
                    LogAir logAir = new LogAir();
                    logAir.setFormaldehyde(formaldehyde);
                    logAir.setTvoc(tvoc);
                    logAir.setPm(pm);
                    logAir.setTemperature(temperature);
                    logAir.setHumidity(humidity);
                    logAir.setAirQuality(airQuality);
                    logAir.setCarbonDioxide(carbonDioxide);
                    logAir.setCreateTime(new Date());
                    logAir.setWarehouseId(1);
                    logAirService.insert(logAir);
                }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            socket.close();
        }
    }






}
